package com.george.shiro.model.controller;

import com.george.shiro.constants.CommonConst;
import com.george.shiro.enums.ResponseStatus;
import com.george.shiro.exception.MyExceptions;
import com.george.shiro.result.ResponseVO;
import com.george.shiro.util.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.lang.reflect.UndeclaredThrowableException;

/**
 * <p>
 *  定义全局的 controller 异常处理类
 *
 *  @ControllerAdvice 和 @ExceptionHandler组合
 *  可以捕获全局controller异常，
 *  不能捕获拦截器Interceptor层异常,
 *  如果需要捕获业务层service异常，需要自定义异常类进行抛出
 * </p>
 *
 * @author GeorgeChan 2019/5/24 17:09
 * @version 1.0
 * @since jdk1.8
 */
@Slf4j
@ControllerAdvice
public class ExceptionHandleController {
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResponseVO handle(Throwable e) {
        if (e instanceof MyExceptions) {
            return ResultUtil.error(e.getMessage());
        }
        if (e instanceof UndeclaredThrowableException) {
            e = ((UndeclaredThrowableException) e).getUndeclaredThrowable();
        }
        // 获取异常信息，如果存在于自定义的异常枚举中，返回异常信息。
        ResponseStatus responseStatus = ResponseStatus.getResponseStatus(e.getMessage());
        if (responseStatus != null) {
            log.error(e.getMessage());
            return ResultUtil.error(responseStatus.getCode(), e.getMessage());
        }
        // 打印异常栈
        e.printStackTrace();
        // 否则返回 “服务器未知错误”
        return ResultUtil.error(CommonConst.DEFAULT_ERROR_CODE, ResponseStatus.ERROR.getMessage());
    }
}
